package com.shop.loan.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.shop.loan.mapper.*;
import com.shop.loan.model.common.Code;
import com.shop.loan.model.common.ResResult;
import com.shop.loan.model.entity.*;
import com.shop.loan.model.enums.*;
import com.shop.loan.model.vo.ContractCodeVo;
import com.shop.loan.model.vo.PayOrderByOfflineVo;
import com.shop.loan.model.vo.RentalPayVo;
import com.shop.loan.qiniu.QiNiuUtil;
import com.shop.loan.redis.RedisCache;
import com.shop.loan.redis.RedisLockUtil;
import com.shop.loan.redis.RedisUtil;
import com.shop.loan.rentaldata.RentalDataUtil;
import com.shop.loan.rentaldata.RentalPayUtil;
import com.shop.loan.service.AsyncService;
import com.shop.loan.util.doc.ContractDocUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import xyz.erupt.annotation.model.Column;
import xyz.erupt.annotation.model.Row;
import xyz.erupt.annotation.query.Condition;
import xyz.erupt.upms.service.EruptUserService;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Component
public class LoanOrderUtil {

    public final static String orderListByIdWidth = "120px";
    public final static String orderListByUserWidth = "250px";
    public final static String orderListByChannelWidth = "100px";
    public final static String orderListByStatusWidth = "100px";
    public final static String orderListBySignStatusWidth = "100px";
    public final static String orderListByServiceUserWidth = "100px";
    public final static String orderListByMoneyWidth = "100px";
    public final static String orderListByRateMoneyWidth = "100px";
    public final static String orderListByPayMoneyWidth = "100px";
    public final static String orderListByDiscountsMoneyWidth = "100px";
    public final static String orderListByOrderNumWidth = "90px";
    public final static String orderListByYearRateWidth = "90px";
    public final static String orderListByBankInfoWidth = "250px";
    public final static String orderListByPeriodWidth = "80px";
    public final static String orderListByPeriodDayWidth = "80px";
    public final static String orderListByOverdueStatusWidth = "80px";
    public final static String orderListByOverdueDayWidth = "80px";
    public final static String orderListByHisOverdueStatusWidth = "100px";
    public final static String orderListByOrderLocationWidth = "200px";


    @Resource
    ContractByMybatisMapper contractByMybatisMapper;

    @Resource
    LoanOrderByMybatisMapper loanOrderByMybatisMapper;

    @Resource
    UserByMybatisMapper userByMybatisMapper;

    @Resource
    UserAuthLogByMybatisMapper userAuthLogByMybatisMapper;

    @Lazy
    @Resource
    RentalDataUtil rentalDataUtil;

    @Resource
    RentalPayUtil rentalPayUtil;

    @Resource
    ContractDocUtil contractDocUtil;

    @Resource
    RedisCache redisCache;

    @Resource
    QiNiuUtil qiNiuUtil;

    @Resource
    LoanOrderContractByMybatisMapper loanOrderContractByMybatisMapper;

    @Resource
    EruptUserByMybatisMapper eruptUserByMybatisMapper;

    @Resource
    RedisUtil redisUtil;

    @Resource
    Util util;

    @Resource
    EruptUserService eruptUserService;

    @Resource
    LoanOrderBillByMybatisMapper loanOrderBillByMybatisMapper;

    @Resource
    RedisLockUtil redisLockUtil;

    @Resource
    LoanOrderPayLogByMybatisMapper loanOrderPayLogByMybatisMapper;

    @Resource
    UserBankByMybatisMapper userBankByMybatisMapper;

    @Resource
    LoanOrderSignLogByMybatisMapper loanOrderSignLogByMybatisMapper;

    @Resource
    PayOrderThirdByMybatisMapper payOrderThirdByMybatisMapper;

    @Resource
    AsyncService asyncService;

    /**
     * 更新订单合同
     *
     * @param orderId
     */
    public List<LoanOrderContractByMybatis> updateOrderContract(Long orderId) {
        UserByMybatis userByMybatis = userByMybatisMapper.selectByOrderId(orderId);
        if (userByMybatis == null || userByMybatis.getId() == null) {
            log.error("准备更新用户合同-用户不存在,订单id:{}", orderId);
            return null;
        }
        List<LoanOrderContractByMybatis> orderContractList = fillContract(orderId);
        if (orderContractList != null && orderContractList.size() > 0) {
            loanOrderContractByMybatisMapper.deleteByOrderId(orderId);
            for (LoanOrderContractByMybatis orderContractByMybatis : orderContractList) {
                loanOrderContractByMybatisMapper.insertSelective(orderContractByMybatis);
            }
        }
        log.warn("完成更新用户合同,订单Id:{}，合同数量:{}", orderId, orderContractList.size());
        return orderContractList;
    }


    /**
     * 填充合同数据
     *
     * @param orderId
     * @return
     */
    public List<LoanOrderContractByMybatis> fillContract(Long orderId) {
        List<LoanOrderContractByMybatis> contractByMybatisList = new ArrayList<>();

        LoanOrderByMybatis loanOrderByMybatis = loanOrderByMybatisMapper.selectByPrimaryKey(orderId);
        if (loanOrderByMybatis == null || loanOrderByMybatis.getId() == null) {
            return null;
        }
        UserByMybatis user = userByMybatisMapper.selectByPrimaryKey(loanOrderByMybatis.getUserId());
        try {
            //合同信息
            ContractByMybatis contractS = new ContractByMybatis();
            contractS.setStatus(true);
            List<ContractByMybatis> orderContractList = contractByMybatisMapper.selectByList(contractS);
            if (orderContractList == null || orderContractList.size() == 0) {
                log.error("合同生成失败，系统合同文件为空");
                return null;
            }
            /**
             * 合同签署内容填充
             */
            ContractCodeVo contractCodeVo = new ContractCodeVo(loanOrderByMybatis, user);
            initContractCode(contractCodeVo, loanOrderByMybatis);
            for (ContractByMybatis contract : orderContractList) {
                LoanOrderContractByMybatis orderContract = new LoanOrderContractByMybatis();
                orderContract.setOrderId(loanOrderByMybatis.getId());
                orderContract.setName(contract.getName());
                orderContract.setContractId(contract.getId());
                orderContract.setType(contract.getType());
                String contractPath = contractDocUtil.replaceContractKey(contractCodeVo, contract);
                orderContract.setUrl(qiNiuUtil.upLoadByFilePath(contractPath, null));
                orderContract.setContractLocalPath(contractPath);

                contractByMybatisList.add(orderContract);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(Util.GetErrorDetails(e));
        }
        return contractByMybatisList;
    }

    private void initContractCode(ContractCodeVo contractCodeVo, LoanOrderByMybatis loanOrderByMybatis) {
        //公司
//        CompanyByMybatis companyByMybatis = redisCache.getCompany(CompanyType.loan);
//        if (companyByMybatis != null) {
//            contractCodeVo.setLoanCompanyAddress(companyByMybatis.getAddress());
//            contractCodeVo.setLoanCompanyLegalName(companyByMybatis.getLegalName());
//            contractCodeVo.setLoanCompanyPhone(companyByMybatis.getPhone());
//            contractCodeVo.setLoanCompanyName(companyByMybatis.getName());
//        }
//        companyByMybatis = redisCache.getCompany(CompanyType.asset);
//        if (companyByMybatis != null) {
//            contractCodeVo.setAssetCompanyBankName(companyByMybatis.getBankName());
//            contractCodeVo.setAssetCompanyBankNumber(companyByMybatis.getBankNumber());
//            contractCodeVo.setAssetCompanyName(companyByMybatis.getName());
//            contractCodeVo.setAssetCompanyBankAccount(companyByMybatis.getBankAccountName());
//        }
//        companyByMybatis = redisCache.getCompany(CompanyType.rd);
//        if (companyByMybatis != null) {
//            contractCodeVo.setRdCompanyAddress(companyByMybatis.getAddress());
//            contractCodeVo.setRdCompanyLegalName(companyByMybatis.getLegalName());
//            contractCodeVo.setRdCompanyPhone(companyByMybatis.getPhone());
//            contractCodeVo.setRdCompanyName(companyByMybatis.getName());
//        }

        //账单列表
        List<LoanOrderBillByMybatis> billByMybatisList = loanOrderBillByMybatisMapper.selectListByOrder(contractCodeVo.getLoanOrderId());
        if (billByMybatisList != null && billByMybatisList.size() > 0) {
            for (int i = 0; i < billByMybatisList.size(); i++) {
                LoanOrderBillByMybatis itemBill = billByMybatisList.get(i);
                if (i == 0) {
                    contractCodeVo.setPeriodDay_1(DateUtil.formatDate(itemBill.getPayTime()));
                    contractCodeVo.setPeriodGuarantee_1(itemBill.getShopMoney());
                    contractCodeVo.setPeriodMoney(itemBill.getMoney().add(itemBill.getRateMoney()));
                }

                if (i == billByMybatisList.size() - 1) {
                    contractCodeVo.setPeriodDay_2(DateUtil.formatDate(itemBill.getPayTime()));
                    contractCodeVo.setPeriodGuarantee_2(itemBill.getShopMoney());
                }
            }
        }
        //银行卡
        UserBankByMybatis userBankByMybatis = userBankByMybatisMapper.selectByPrimaryKey(loanOrderByMybatis.getBankId());
        if (userBankByMybatis != null) {
            contractCodeVo.setBankName(userBankByMybatis.getBankName());
            contractCodeVo.setBankNumber(userBankByMybatis.getCarNo());
        }

        contractCodeVo.setReason("数码产品");
        if (loanOrderByMybatis.getReasonType() != null) {
            if (loanOrderByMybatis.getReasonType() == 0) {
                contractCodeVo.setReason("数码产品");
            } else if (loanOrderByMybatis.getReasonType() == 1) {
                contractCodeVo.setReason("家装建材");
            } else if (loanOrderByMybatis.getReasonType() == 2) {
                contractCodeVo.setReason("旅游消费");
            } else if (loanOrderByMybatis.getReasonType() == 3) {
                contractCodeVo.setReason("综合消费");
            } else if (loanOrderByMybatis.getReasonType() == 4) {
                contractCodeVo.setReason("教育支出");
            } else if (loanOrderByMybatis.getReasonType() == 5) {
                contractCodeVo.setReason("健康医疗");
            } else if (loanOrderByMybatis.getReasonType() == 6) {
                contractCodeVo.setReason("大额消费品");
            } else if (loanOrderByMybatis.getReasonType() == 9) {
                contractCodeVo.setReason("其他事由");
            }
        }
    }

    /**
     * 获取合同签字的key
     *
     * @param contractType
     * @param contractUserType
     * @return
     */
    public String getSignKey(ContractType contractType, ContractUserType contractUserType) {
        if (contractType.getType().intValue() == ContractType.loan.getType().intValue()) {
            //借款合同
            if (contractUserType.getType().intValue() == ContractUserType.user.getType()) {
                return "乙 方:";
            } else if (contractUserType.getType().intValue() == ContractUserType.loan.getType()) {
                return "甲 方:";
            }
        } else if (contractType.getType().intValue() == ContractType.loan_notify.getType().intValue()) {
            //贷款告知书
            return "签字人（借款人）：";
        } else if (contractType.getType().intValue() == ContractType.guarantee_contract.getType().intValue()) {
            //担保合同
            if (contractUserType.getType().intValue() == ContractUserType.user.getType()) {
                return "甲方：";
            } else if (contractUserType.getType().intValue() == ContractUserType.rd.getType()) {
                return "乙方：";
            }
        } else if (contractType.getType().intValue() == ContractType.credit.getType().intValue()) {
            //个人征信授权书
            return "本人姓名：";
        } else if (contractType.getType().intValue() == ContractType.guarantee_apply.getType().intValue()) {
            //委托担保合同
            return "申请人：";
        } else if (contractType.getType().intValue() == ContractType.debenture_transfer.getType().intValue()) {
            //债券转让通知书
            if (contractUserType.getType().intValue() == ContractUserType.user.getType()) {
                return "签收人（借款人/担保人）：";
            } else if (contractUserType.getType().intValue() == ContractUserType.loan.getType()) {
                return "债权转让人：";
            }
        }
        return null;
    }


    /**
     * 查询订单数据（今日/明日）
     *
     * @param list
     * @param poolType  1:放款池  2：今日/明日到期池
     * @param payStatus
     * @param startTime
     * @param endTime
     */
    public void searchDayOrderList(Collection<Map<String, Object>> list,
                                   Integer poolType, Boolean payStatus,
                                   String startTime, String endTime) {
        String pageIndexStr = util.getSearchParam("pageIndex", 1);
        String pageSizeStr = util.getSearchParam("pageSize", 1);
        pageIndexStr = pageIndexStr == null ? "1" : pageIndexStr;
        pageSizeStr = pageSizeStr == null ? "10" : pageSizeStr;

        LoanOrderByMybatis search = getDayOrderListSearch(poolType, payStatus, startTime, endTime);
        String hideEndStr = util.getSearchParam("hideEnd", 1);
        search.setPayStatus(0);
        if (StringUtils.hasLength(hideEndStr)) {
            if (Integer.parseInt(hideEndStr) == 0) {
//                0:全部  1：已还  2：未还
                search.setPayStatus(null);
            } else if (Integer.parseInt(hideEndStr) == 1) {
                search.setPayStatus(1);
            }
        }
        if (payStatus != null) {
            search.setPayStatus(payStatus ? 1 : 0);
        }

        PageHelper.startPage(Integer.parseInt(pageIndexStr), Integer.parseInt(pageSizeStr));
        Page<LoanOrderByMybatis> userOrderByMybatisList = loanOrderByMybatisMapper.selectOrderListByDay(search);
        if (userOrderByMybatisList == null || userOrderByMybatisList.size() == 0) {
            return;
        }
        for (LoanOrderByMybatis userOrderByMybatis : userOrderByMybatisList) {
            userOrderByMybatis.setPageIndex(userOrderByMybatisList.getPageNum());
            userOrderByMybatis.setPageSize(userOrderByMybatisList.getPageSize());
            userOrderByMybatis.setTotal(userOrderByMybatisList.getTotal());
            userOrderByMybatis.setTotalPage(userOrderByMybatisList.getPages());

            Map map = JSON.parseObject(JSON.toJSONString(userOrderByMybatis), Map.class);
            map.put("shouldPayMoney", "0");
            map.put("actualPayMoney", "0");
            map.put("discountsMoney", "0");

            search.setId(userOrderByMybatis.getId());
            //查询应还/已还金额
            LoanOrderBillByMybatis loanOrderBillByMybatis = loanOrderBillByMybatisMapper.selectSum(search);
            if (loanOrderBillByMybatis != null) {
                map.put("shouldPayMoney", loanOrderBillByMybatis.getMoney().add(loanOrderBillByMybatis.getRateMoney()).add(loanOrderBillByMybatis.getShopMoney()));
                map.put("actualPayMoney", loanOrderBillByMybatis.getPayMoney());
                map.put("discountsMoney", loanOrderBillByMybatis.getDiscountsMoney());
            }
            list.add(map);
        }
    }


    /**
     * 查询订单数据（部分还款）
     *
     * @param list
     */
    public void searchPartOrderList(Collection<Map<String, Object>> list) {
        String pageIndexStr = util.getSearchParam("pageIndex", 1);
        String pageSizeStr = util.getSearchParam("pageSize", 1);
        pageIndexStr = pageIndexStr == null ? "1" : pageIndexStr;
        pageSizeStr = pageSizeStr == null ? "10" : pageSizeStr;

        LoanOrderByMybatis search = getDayOrderListSearch(null, null, null, null);
        PageHelper.startPage(Integer.parseInt(pageIndexStr), Integer.parseInt(pageSizeStr));
        Page<LoanOrderByMybatis> userOrderByMybatisList = loanOrderByMybatisMapper.selectOrderListByPart(search);
        if (userOrderByMybatisList == null || userOrderByMybatisList.size() == 0) {
            return;
        }
        for (LoanOrderByMybatis userOrderByMybatis : userOrderByMybatisList) {
            userOrderByMybatis.setPageIndex(userOrderByMybatisList.getPageNum());
            userOrderByMybatis.setPageSize(userOrderByMybatisList.getPageSize());
            userOrderByMybatis.setTotal(userOrderByMybatisList.getTotal());
            userOrderByMybatis.setTotalPage(userOrderByMybatisList.getPages());

            Map map = JSON.parseObject(JSON.toJSONString(userOrderByMybatis), Map.class);
            list.add(map);
        }
    }


    public void updateShowDayList(Collection<Map<String, Object>> list) {
        for (Map<String, Object> stringObjectMap : list) {
            if (stringObjectMap.containsKey("loanServiceId") && stringObjectMap.get("loanServiceId") != null) {
                Long id = Long.parseLong(stringObjectMap.get("loanServiceId").toString());
                EruptUserByMybatis eruptUserByMybatis = eruptUserByMybatisMapper.selectByPrimaryKey(id);
                if (eruptUserByMybatis != null) {
                    stringObjectMap.put("loanServiceUser_name", eruptUserByMybatis.getName());
                }
            }

            if (stringObjectMap.containsKey("authServiceId") && stringObjectMap.get("authServiceId") != null) {
                Long id = Long.parseLong(stringObjectMap.get("authServiceId").toString());
                EruptUserByMybatis eruptUserByMybatis = eruptUserByMybatisMapper.selectByPrimaryKey(id);
                if (eruptUserByMybatis != null) {
                    stringObjectMap.put("authServiceUser_name", eruptUserByMybatis.getName());
                }
            }

            if (stringObjectMap.containsKey("afterServiceId") && stringObjectMap.get("afterServiceId") != null) {
                Long id = Long.parseLong(stringObjectMap.get("afterServiceId").toString());
                EruptUserByMybatis eruptUserByMybatis = eruptUserByMybatisMapper.selectByPrimaryKey(id);
                if (eruptUserByMybatis != null) {
                    stringObjectMap.put("afterServiceUser_name", eruptUserByMybatis.getName());
                }
            }

            if (stringObjectMap.containsKey("createTime") && stringObjectMap.get("createTime") != null) {
                stringObjectMap.put("createTime", LocalDateTimeUtil.of(Long.parseLong(stringObjectMap.get("createTime").toString())));
            }
            if (stringObjectMap.containsKey("loanTime") && stringObjectMap.get("loanTime") != null) {
                stringObjectMap.put("loanTime", LocalDateTimeUtil.of(Long.parseLong(stringObjectMap.get("loanTime").toString())));
            }
//            if (stringObjectMap.containsKey("finishTime") && stringObjectMap.get("finishTime") != null) {
//                stringObjectMap.put("finishTime", LocalDateTimeUtil.of(Long.parseLong(stringObjectMap.get("finishTime").toString())));
//            }
//            stringObjectMap.put("user_name", stringObjectMap.get("user_name") + "【" + stringObjectMap.get("user_mobile") + "】");
            stringObjectMap.put("user_name", "姓名：" + stringObjectMap.get("user_name") + "\n 手机号：" + stringObjectMap.get("user_mobile") + "\n 身份证：" + stringObjectMap.get("card_num"));

        }

    }


    /**
     * 今日/明日列表合计列
     *
     * @param payStatus
     * @param startTime
     * @param endTime
     * @return
     */
    public List<Row> searchDayOrderExtraRow(Integer poolType, Boolean payStatus, String startTime, String endTime) {
        //行对象
        List<Row> rows = new ArrayList<>();

        BigDecimal money = BigDecimal.ZERO, payMoney = BigDecimal.ZERO, payMoneyByGuarantee = BigDecimal.ZERO, rateMoney = BigDecimal.ZERO, guarantee = BigDecimal.ZERO;
        LoanOrderByMybatis loanOrderByMybatis = getDayOrderListSearch(poolType, payStatus, startTime, endTime);
        loanOrderByMybatis.setOrdOverdueStatus(true);

        String hideEndStr = util.getSearchParam("hideEnd", 1);
        loanOrderByMybatis.setPayStatus(0);
        if (StringUtils.hasLength(hideEndStr)) {
            if (Integer.parseInt(hideEndStr) == 0) {
//                0:全部  1：已还  2：未还
                loanOrderByMybatis.setPayStatus(null);
            } else if (Integer.parseInt(hideEndStr) == 1) {
                loanOrderByMybatis.setPayStatus(1);
            }
        }
        if (payStatus != null) {
            loanOrderByMybatis.setPayStatus(payStatus ? 1 : 0);
        }

        LoanOrderBillByMybatis loanOrderBillByMybatis = loanOrderBillByMybatisMapper.selectSum(loanOrderByMybatis);
        if (loanOrderBillByMybatis != null) {
            money = loanOrderBillByMybatis.getMoney();
            payMoney = loanOrderBillByMybatis.getPayMoney();
            rateMoney = loanOrderBillByMybatis.getRateMoney();
            guarantee = loanOrderBillByMybatis.getShopMoney();
        }

        //列对象
        List<Column> totalColumns = new ArrayList<>();
        totalColumns.add(Column.builder().value("").colspan(1).build());
        totalColumns.add(Column.builder().value("应还金额：" + money.add(rateMoney).add(guarantee)).colspan(1).className("text-green").build());
        totalColumns.add(Column.builder().value("已还金额：" + payMoney.add(payMoneyByGuarantee)).colspan(1).className("text-green").build());

        rows.add(Row.builder().columns(totalColumns).build());
        return rows;
    }


    /**
     * 订单列表查询条件
     *
     * @param payStatus
     * @param startTime
     * @param endTime
     * @return
     */
    public LoanOrderByMybatis getDayOrderListSearch(Integer poolType, Boolean payStatus, String startTime, String endTime) {
        Long loginServiceUserId = null;

        EruptUserByMybatis eruptUserByMybatis = eruptUserByMybatisMapper.selectByPrimaryKey(eruptUserService.getCurrentUid());
        if (!eruptUserByMybatis.getIsAdmin()) {
            //非超级管理 只能看领取的订单
            loginServiceUserId = eruptUserByMybatis.getId();
        }
        String orderNumStr = util.getSearchParam("orderNum", 0);
        String afterServiceUserId = util.getSearchParam("afterServiceUser", 0);
        String loanServiceUserId = util.getSearchParam("loanServiceUser", 0);
        String authServiceUserId = util.getSearchParam("authServiceUser", 0);
        String collectionServiceUserId = util.getSearchParam("collectionServiceUser", 0);
        String overdueStatusStr = util.getSearchParam("overdueStatus", 0);
        String hisOverdueStatusStr = util.getSearchParam("hisOverdueStatus", 0);
        String createTimeStartStr = util.getSearchParam("createTime", 0);
        String createTimeEndStr = util.getSearchParam("createTime", 1);
        String loanTimeStartStr = util.getSearchParam("loanTime", 0);
        String loanTimeEndStr = util.getSearchParam("loanTime", 1);
        String channelIdStr = util.getSearchParam("channel", 1);
        String statusStr = util.getSearchParam("status", 1);
        String orderIdStr = util.getSearchParam("orderId", 1);
        String userWillStr = util.getSearchParam("userWill", 1);
        String hasDiscountsStr = util.getSearchParam("hasDiscounts", 1);
        String partPayStr = util.getSearchParam("partPay", 1);
        String periodNumStr = util.getSearchParam("periodNum", 1);
        String userTypeStr = util.getSearchParam("userType", 1);

        String payTimeStartStr = util.getSearchParam("payTime", 0);
        String payTimeEndStr = util.getSearchParam("payTime", 1);


        LoanOrderByMybatis search = new LoanOrderByMybatis();
        search.setStartTime(startTime);
        search.setEndTime(endTime);

        if (StringUtils.hasLength(periodNumStr)) {
            search.setPeriodNum(Integer.parseInt(periodNumStr));
        }
        if (StringUtils.hasLength(userTypeStr)) {
            search.setUserType(Integer.parseInt(userTypeStr));
        }
        if (StringUtils.hasLength(userWillStr)) {
            search.setUserWill(Integer.parseInt(userWillStr));
        }
        if (StringUtils.hasText(orderNumStr)) {
            search.setOrderNum(Integer.valueOf(orderNumStr));
        }
        if (StringUtils.hasText(orderIdStr)) {
            search.setId(Long.valueOf(orderIdStr));
        }
        if (StringUtils.hasText(statusStr)) {
            search.setStatus(Integer.valueOf(statusStr));
        }
        if (StringUtils.hasText(channelIdStr)) {
            search.setChannelId(Long.valueOf(channelIdStr));
        }
        if (StringUtils.hasText(createTimeStartStr)) {
            search.setStartTimeByCreate(createTimeStartStr);
        }
        if (StringUtils.hasText(createTimeEndStr)) {
            search.setEndTimeByCreate(createTimeEndStr);
        }
        if (StringUtils.hasText(payTimeStartStr)) {
            search.setStartTimeByPay(payTimeStartStr);
        }
        if (StringUtils.hasText(payTimeEndStr)) {
            search.setEndTimeByPay(payTimeEndStr);
        }
        if (StringUtils.hasText(createTimeEndStr)) {
            search.setEndTimeByCreate(createTimeEndStr);
        }
        if (StringUtils.hasText(loanTimeStartStr)) {
            search.setStartTimeByLoan(loanTimeStartStr);
        }
        if (StringUtils.hasText(loanTimeEndStr)) {
            search.setEndTimeByLoan(loanTimeEndStr);
        }
        if (StringUtils.hasText(afterServiceUserId)) {
            search.setAfterServiceId(Long.valueOf(afterServiceUserId));
        }
        if (StringUtils.hasText(loanServiceUserId)) {
            search.setAfterServiceId(Long.valueOf(loanServiceUserId));
        }
        if (StringUtils.hasText(authServiceUserId)) {
            search.setAfterServiceId(Long.valueOf(authServiceUserId));
        }
        if (StringUtils.hasText(collectionServiceUserId)) {
            search.setCollectionServiceId(Long.valueOf(collectionServiceUserId));
        }
        if (StringUtils.hasText(overdueStatusStr)) {
            search.setOverdueStatus(Boolean.valueOf(overdueStatusStr));
        }
        if (StringUtils.hasText(hisOverdueStatusStr)) {
            search.setHisOverdueStatus(Boolean.valueOf(hisOverdueStatusStr));
        }
        if (StringUtils.hasText(hasDiscountsStr)) {
            search.setHasDiscounts(Integer.parseInt(hasDiscountsStr));
        }
        if (StringUtils.hasText(partPayStr)) {
            search.setIsPart(Integer.parseInt(partPayStr));
        }
        if (payStatus != null) {
            search.setPayStatus(payStatus ? 1 : 0);
        }

        search.setPoolType(poolType);
        search.setLoginServiceUserId(loginServiceUserId);
        search.setUserIds(getUserIdBySearch());
        return search;
    }


    public String getOrderListBeforeFetch(String className, List<Condition> conditions) {
        conditions.removeIf(condition -> "userName".trim().equals(condition.getKey()) || "userPhone".trim().equals(condition.getKey())
                || "cardAddress".trim().equals(condition.getKey()) || "partPay".trim().equals(condition.getKey())
                || "hasDiscounts".trim().equals(condition.getKey()) || "periodNum".trim().equals(condition.getKey())
                || "userType".trim().equals(condition.getKey()) || "payTime".trim().equals(condition.getKey()));

        String sql = "1 = 1";
        EruptUserByMybatis eruptUserByMybatis = eruptUserByMybatisMapper.selectByPrimaryKey(eruptUserService.getCurrentUid());
        if (!eruptUserByMybatis.getIsAdmin()) {
            //非超级管理 只能看领取的订单
            if (className.contains("ByLoan")) {
                sql = sql + " and " + className + ".loanServiceUser.id=" + eruptUserByMybatis.getId();
            } else if (className.contains("ByOverdue")) {
                sql = sql + " and " + className + ".collectionServiceUser.id=" + eruptUserByMybatis.getId();
            } else if (className.contains("ByTom") || className.contains("ByToday")) {
                sql = sql + " and " + className + ".afterServiceUser.id=" + eruptUserByMybatis.getId();
            } else {
                sql = sql + " and " + className + ".authServiceUser.id=" + eruptUserByMybatis.getId();
                //            sql = sql + " and (" + className + ".loanServiceUser.id=" + eruptUserByMybatis.getId() + " or " + className + ".authServiceUser.id=" + eruptUserByMybatis.getId()
//                    + " or " + className + ".afterServiceUser.id=" + eruptUserByMybatis.getId() + " or " + className + ".collectionServiceUser.id=" + eruptUserByMybatis.getId() + ")";
            }

        }

        List<Long> userIds = getUserIdBySearch();
        String userIdStr = null;
        if (userIds != null && userIds.size() > 0) {
            userIdStr = org.apache.commons.lang3.StringUtils.join(userIds, ",");
        }
        if (StringUtils.hasLength(userIdStr)) {
            sql = sql + " and " + className + ".userId in (" + userIdStr + ")";
        }

        String partPay = util.getSearchParam("partPay", 0);
        if (StringUtils.hasText(partPay)) {
            if (Integer.parseInt(partPay) == 1) {
                //有还款
                sql = sql + " and (" + className + ".payMoney > 0 or " + className + ".payMoneyByGuarantee > 0)";
            }
        }
        String hasDiscounts = util.getSearchParam("hasDiscounts", 0);
        if (StringUtils.hasText(hasDiscounts)) {
            if (Integer.parseInt(hasDiscounts) == 1) {
                //有优惠
                sql = sql + " and (" + className + ".discountsMoney > 0 or " + className + ".discountsMoneyByGoods > 0)";
            }
        }
        String userTypeStr = util.getSearchParam("userType", 0);
        if (StringUtils.hasLength(userTypeStr)) {
//            @VL(label = "全部", value = "1"),
//            @VL(label = "新客户", value = "2"),
//            @VL(label = "老客户", value = "3"),
            if ("2".equals(userTypeStr)) {
                sql = sql + " and " + className + ".orderNum = 1";
            } else if ("3".equals(userTypeStr)) {
                sql = sql + " and " + className + ".orderNum > 1";
            }
        }


        LoanOrderByMybatis search = getDayOrderListSearch(null, null, null, null);
        if (search.getStartTimeByPay() != null && search.getEndTimeByPay() != null) {
            PageHelper.startPage(1, 9999999);
            List<Long> orderIds = loanOrderBillByMybatisMapper.selectListById(search);
            if (orderIds == null || orderIds.size() == 0) {
                orderIds = new ArrayList<>();
                orderIds.add(-1L);
            }
            String orderIdStr = org.apache.commons.lang3.StringUtils.join(orderIds, ",");
            if (StringUtils.hasLength(orderIdStr)) {
                sql = sql + " and " + className + ".id in (" + orderIdStr + ")";
            }
        }
        return sql;
    }


    public String getOrderListBeforeFetchByMybatis(String className, String tableName) {
        String sql = "1 = 1";
        EruptUserByMybatis eruptUserByMybatis = eruptUserByMybatisMapper.selectByPrimaryKey(eruptUserService.getCurrentUid());
        if (!eruptUserByMybatis.getIsAdmin()) {
            //非超级管理 只能看领取的订单
            if (tableName.contains("ByLoan")) {
                sql = sql + " and " + className + ".loan_service_id=" + eruptUserByMybatis.getId();
            } else if (tableName.contains("ByOverdue")) {
                sql = sql + " and " + className + ".collection_service_id=" + eruptUserByMybatis.getId();
            } else if (tableName.contains("ByTom") || tableName.contains("ByToday")) {
                sql = sql + " and " + className + ".after_service_id=" + eruptUserByMybatis.getId();
            } else {
                sql = sql + " and " + className + ".auth_service_id.id=" + eruptUserByMybatis.getId();
                //            sql = sql + " and (" + className + ".loanServiceUser.id=" + eruptUserByMybatis.getId() + " or " + className + ".authServiceUser.id=" + eruptUserByMybatis.getId()
//                    + " or " + className + ".afterServiceUser.id=" + eruptUserByMybatis.getId() + " or " + className + ".collectionServiceUser.id=" + eruptUserByMybatis.getId() + ")";
            }
//            sql = "(" + className + ".loan_service_id=" + eruptUserByMybatis.getId() + " or " + className + ".auth_service_id=" + eruptUserByMybatis.getId()
//                    + " or " + className + ".after_service_id=" + eruptUserByMybatis.getId() + " or " + className + ".collection_service_id=" + eruptUserByMybatis.getId() + ")";
        }

        List<Long> userIds = getUserIdBySearch();
        String userIdStr = null;
        if (userIds != null && userIds.size() > 0) {
            userIdStr = org.apache.commons.lang3.StringUtils.join(userIds, ",");
        }
        if (StringUtils.hasLength(userIdStr)) {
            sql = sql + " and " + className + ".user_id in (" + userIdStr + ")";
        }

        String partPay = util.getSearchParam("partPay", 0);
        if (StringUtils.hasText(partPay)) {
            if (Integer.parseInt(partPay) == 1) {
                //有还款
                sql = sql + " and (" + className + ".pay_money > 0 or " + className + ".pay_money_by_guarantee > 0)";
            }
        }
        String hasDiscounts = util.getSearchParam("hasDiscounts", 0);
        if (StringUtils.hasText(hasDiscounts)) {
            if (Integer.parseInt(hasDiscounts) == 1) {
                //有优惠
                sql = sql + " and (" + className + ".discounts_money > 0 or " + className + ".discounts_money_by_guarantee > 0)";
            }
        }
        return sql;
    }


    /**
     * 根据手机号码/姓名查询用户id
     *
     * @return
     */
    public List<Long> getUserIdBySearch() {
        String userName = util.getSearchParam("userName", 0);
        String userPhone = util.getSearchParam("userPhone", 0);
        String cardAddress = util.getSearchParam("cardAddress", 0);

        if (StringUtils.hasLength(userName) || StringUtils.hasLength(userPhone)) {
            PageHelper.startPage(1, 9999999);
            List<Long> ids = userByMybatisMapper.selectIdByMobileName(userPhone, userName, cardAddress);
            if (ids == null || ids.size() == 0) {
                ids = new ArrayList<>();
                ids.add(-1L);
            }
            return ids;
        }
        return null;
    }


    /**
     * 还款/优惠操作
     *
     * @param payOrderByOfflineVo
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public ResResult orderPay(PayOrderByOfflineVo payOrderByOfflineVo) {
        if (payOrderByOfflineVo.getOrderId() == null || payOrderByOfflineVo.getPeriod() == null || payOrderByOfflineVo.getMoney() == null) {
            return new ResResult(Code.PARAM_LACK);
        }
        if (payOrderByOfflineVo.getMoney().doubleValue() <= 0) {
            return new ResResult(Code.PARAM_INVALID);
        }
        String lockValue = String.valueOf(System.currentTimeMillis());
        String lockKey = RedisCache.orderPaymentLock + payOrderByOfflineVo.getOrderId();
        Jedis jedis = redisUtil.getJedis();
        try {
            if (!redisLockUtil.lock(jedis, lockKey, lockValue)) {
                return new ResResult(Code.RATE_HIGH);
            }
            List<LoanOrderBillByMybatis> loanOrderBillByMybatisList = loanOrderBillByMybatisMapper.selectListByOrder(payOrderByOfflineVo.getOrderId());
            LoanOrderByMybatis loanOrderByMybatis = loanOrderByMybatisMapper.selectByPrimaryKey(payOrderByOfflineVo.getOrderId());
            if (loanOrderByMybatis == null || loanOrderBillByMybatisList == null || loanOrderBillByMybatisList.size() <= 0) {
                return new ResResult(Code.PARAM_INVALID);
            }

            Long billId = null;
            for (LoanOrderBillByMybatis loanOrderBillByMybatis : loanOrderBillByMybatisList) {
                if (loanOrderBillByMybatis.getPeriod() == payOrderByOfflineVo.getPeriod().intValue()) {
                    LoanOrderBillByMybatis updateBill = new LoanOrderBillByMybatis();
                    updateBill.setId(loanOrderBillByMybatis.getId());
                    updateBill.setOverdueStatus(loanOrderBillByMybatis.getOverdueStatus());

                    if (payOrderByOfflineVo.getPayType() == PayType.principal_interest.getType().intValue()) {
                        loanOrderBillByMybatis.setPayMoney(loanOrderBillByMybatis.getPayMoney().add(payOrderByOfflineVo.getMoney()));
                        updateBill.setPayMoney(loanOrderBillByMybatis.getPayMoney());
                    } else {
//                        loanOrderBillByMybatis.setPayMoneyByGuarantee(loanOrderBillByMybatis.getPayMoneyByGuarantee().add(payOrderByOfflineVo.getMoney()));
//                        updateBill.setPayMoneyByGuarantee(loanOrderBillByMybatis.getPayMoneyByGuarantee());
                    }
                    if (Util.checkIsSettle(loanOrderBillByMybatis)) {
                        //本金+利息 <= 优惠本息+优惠商品金额+还款金额  则结清
                        updateBill.setPayStatus(true);
                        updateBill.setOverdueStatus(true);
                    } else {
                        updateBill.setPayStatus(false);
                    }
                    updateBill.setOpTime(new Date());

                    loanOrderBillByMybatisMapper.updateByPrimaryKeySelective(updateBill);

                    loanOrderBillByMybatis.setPayStatus(updateBill.getPayStatus());
                    if (updateBill.getOverdueStatus() != null) {
                        loanOrderBillByMybatis.setOverdueStatus(updateBill.getOverdueStatus());
                    }

                    billId = loanOrderBillByMybatis.getId();
                }
            }

            LoanOrderByMybatis updateOrder = new LoanOrderByMybatis();
            updateOrder.setId(loanOrderByMybatis.getId());
            updateOrder.setPayMoney(getBillPayMoney(loanOrderBillByMybatisList));
            updateOrder.setDiscountsMoney(getBillDisMoney(loanOrderBillByMybatisList));
            updateOrder.setOverdueStatus(checkBillOverdue(loanOrderBillByMybatisList));
            if (checkBillEnd(loanOrderBillByMybatisList)) {
                updateOrder.setStatus(OrderStatus.end.getStatus());
                updateOrder.setOverdueStatus(true);
                updateOrder.setFinishTime(new Date());
                //订单结束 修改用户完结订单数
                userByMybatisMapper.updateUserEndNum(loanOrderByMybatis.getUserId());
            }
            loanOrderByMybatisMapper.updateByPrimaryKeySelective(updateOrder);

            //添加还款记录
            LoanOrderPayLogByMybatis loanOrderPayLogByMybatis = new LoanOrderPayLogByMybatis();
            loanOrderPayLogByMybatis.setPayOrderId(payOrderByOfflineVo.getOrderPayId());
            loanOrderPayLogByMybatis.setOrderId(payOrderByOfflineVo.getOrderId());
            loanOrderPayLogByMybatis.setUserId(loanOrderByMybatis.getUserId());
            loanOrderPayLogByMybatis.setPayType(payOrderByOfflineVo.getPayType());
            loanOrderPayLogByMybatis.setCreateTime(new Date());
            loanOrderPayLogByMybatis.setBillId(billId);
            loanOrderPayLogByMybatis.setRemark(payOrderByOfflineVo.getRemark());
            loanOrderPayLogByMybatis.setMoney(payOrderByOfflineVo.getMoney());
            loanOrderPayLogByMybatis.setPeriod(payOrderByOfflineVo.getPeriod());
            loanOrderPayLogByMybatis.setIsDelete(false);
            loanOrderPayLogByMybatis.setOnline(payOrderByOfflineVo.getOnline());
            loanOrderPayLogByMybatis.setPaymentType(payOrderByOfflineVo.getPaymentType());
            loanOrderPayLogByMybatisMapper.insertSelective(loanOrderPayLogByMybatis);

            //校验是否需要推送
            asyncService.notifyCheck(payOrderByOfflineVo.getOrderId());
            return new ResResult(Code.SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(Util.GetErrorDetails(e));
        } finally {
            if (jedis != null) {
                redisLockUtil.release(jedis, lockKey, lockValue);
                jedis.close();
            }
        }
        return new ResResult(Code.FAIL);
    }


    /**
     * 校验账单中是否还存在逾期
     *
     * @param loanOrderBillByMybatisList
     * @return
     */
    public Boolean checkBillOverdue(List<LoanOrderBillByMybatis> loanOrderBillByMybatisList) {
        for (LoanOrderBillByMybatis loanOrderBillByMybatis : loanOrderBillByMybatisList) {
            if (loanOrderBillByMybatis.getOverdueStatus() != null && !loanOrderBillByMybatis.getOverdueStatus()) {
                return false;
            }
        }
        return true;
    }

    /**
     * 校验账单中是否还存在待结清
     *
     * @param loanOrderBillByMybatisList
     * @return
     */
    public Boolean checkBillEnd(List<LoanOrderBillByMybatis> loanOrderBillByMybatisList) {
        for (LoanOrderBillByMybatis loanOrderBillByMybatis : loanOrderBillByMybatisList) {
            if (loanOrderBillByMybatis.getPayStatus() != null && !loanOrderBillByMybatis.getPayStatus()) {
                return false;
            }
        }
        return true;
    }

    /**
     * 获取账单已还金额之和
     *
     * @param loanOrderBillByMybatisList
     * @return
     */
    public BigDecimal getBillPayMoney(List<LoanOrderBillByMybatis> loanOrderBillByMybatisList) {
        BigDecimal payMoney = BigDecimal.ZERO;
        for (LoanOrderBillByMybatis loanOrderBillByMybatis : loanOrderBillByMybatisList) {
            payMoney = payMoney.add(loanOrderBillByMybatis.getPayMoney());
        }
        return payMoney;
    }

    /**
     * 获取账单优惠本息之和
     *
     * @param loanOrderBillByMybatisList
     * @return
     */
    public BigDecimal getBillDisMoney(List<LoanOrderBillByMybatis> loanOrderBillByMybatisList) {
        BigDecimal disMoney = BigDecimal.ZERO;
        for (LoanOrderBillByMybatis loanOrderBillByMybatis : loanOrderBillByMybatisList) {
            disMoney = disMoney.add(loanOrderBillByMybatis.getDiscountsMoney());
        }
        return disMoney;
    }

    /**
     * 放款操作
     *
     * @param orderId
     * @return
     */
    public ResResult loan(Long orderId, String loanBy) {
        String lockValue = String.valueOf(System.currentTimeMillis());
        String lockKey = RedisCache.orderLoanLock + orderId;
        Jedis jedis = redisUtil.getJedis();
        try {
            if (!redisLockUtil.lock(jedis, lockKey, lockValue)) {
                return new ResResult(Code.lOAN_ING);
            }
            Integer loanIngNum = payOrderThirdByMybatisMapper.selectLoanStatusByOrder(orderId);
            if (loanIngNum != null && loanIngNum > 0) {
                return new ResResult(Code.lOAN_ING);
            }
            if (redisUtil.hget(RedisCache.orderLoanSuccessMap, orderId + "") != null) {
                return new ResResult(Code.lOAN_ING);
            }
            if (redisUtil.hget(RedisCache.orderLoanIngMap, orderId + "") != null) {
                return new ResResult(Code.lOAN_ING);
            }
            LoanOrderByMybatis loanOrderByMybatis = loanOrderByMybatisMapper.selectByPrimaryKey(orderId);
            if (loanOrderByMybatis == null || loanOrderByMybatis.getStatus() != OrderStatus.wait_loan.getStatus().intValue()) {
                return new ResResult(Code.ORDER_STATUS_ERROR);
            }
            UserBankByMybatis userBankByMybatis = userBankByMybatisMapper.selectByPrimaryKey(loanOrderByMybatis.getBankId());
            if (userBankByMybatis == null || userBankByMybatis.getCarNo() == null) {
                return new ResResult(Code.BANK_EMPTY);
            }
            UserByMybatis userByMybatis = userByMybatisMapper.selectByPrimaryKey(loanOrderByMybatis.getUserId());
            UserAuthLogByMybatis userAuthLogByMybatis = userAuthLogByMybatisMapper.selectByUserId(loanOrderByMybatis.getUserId());
            if (userAuthLogByMybatis == null || !JSON.isValidObject(userAuthLogByMybatis.getOcrInfoByBack())) {
                return new ResResult(Code.USER_IDENTITY_AUTH_LACK);
            }
            JSONObject ocrInfoByBack = JSON.parseObject(userAuthLogByMybatis.getOcrInfoByBack());
            String timelimit = ocrInfoByBack.getJSONObject("info").getString("timelimit");
            if (StringUtils.hasLength(timelimit)) {
                timelimit = timelimit.replaceAll("长期", "29991231");
            }
            /**
             * 放款操作
             */
            String outTradeNo = Util.getOutTradeNo();
            RentalPayVo rentalPayVo = new RentalPayVo();
            rentalPayVo.setAmount(loanOrderByMybatis.getMoney());
            rentalPayVo.setOrderNo(outTradeNo);
            rentalPayVo.setRealName(userByMybatis.getCardName());
            rentalPayVo.setIdNo(userByMybatis.getCardNum());
            rentalPayVo.setCardNo(userBankByMybatis.getCarNo());
            rentalPayVo.setIdValidDate(timelimit);
            rentalPayVo.setOrderId(loanOrderByMybatis.getId() + "");
            rentalPayVo.setUserId(util.getUserId(userByMybatis.getId()));
            ResResult loanRes = rentalPayUtil.loan(rentalPayVo);

            //插入一条放款记录
            PayOrderThirdByMybatis payOrderThird = new PayOrderThirdByMybatis();
            payOrderThird.setOrderId(orderId);
            payOrderThird.setUserId(userByMybatis.getId());
            payOrderThird.setCreateTime(new Date());
            payOrderThird.setAmount(loanOrderByMybatis.getMoney());
            payOrderThird.setOutTradeNo(outTradeNo);
            payOrderThird.setRemark(loanBy);
            payOrderThird.setType(PayOrderType.loan.getType());
            if (loanRes.getCode() == Code.SUCCESS.getCode().intValue()) {
                payOrderThird.setSerialNo(loanRes.getData().toString());
                payOrderThird.setStatus(PayStatus.wait.getStatus());//进行中
                //正在放款订单集合
                redisUtil.hset(RedisCache.orderLoanIngMap, orderId + "", DateUtil.now());
            } else {
                payOrderThird.setStatus(PayStatus.fail.getStatus());
                payOrderThird.setReason(loanRes.getMsg());
            }
            payOrderThirdByMybatisMapper.insertSelective(payOrderThird);
            return loanRes;
        } catch (Exception e) {
            e.printStackTrace();
            log.error(Util.GetErrorDetails(e));
        } finally {
            if (jedis != null) {
                redisLockUtil.release(jedis, lockKey, lockValue);
                jedis.close();
            }
        }
        return new ResResult(Code.FAIL);
    }

    /**
     * 列表数据展示处理
     *
     * @param list
     */
    public void setOrderListData(Collection<Map<String, Object>> list) {
        if (list == null || list.size() == 0) {
            return;
        }
        for (Map<String, Object> stringObjectMap : list) {
            UserByMybatis userByMybatis = userByMybatisMapper.selectByOrderId(Long.valueOf(stringObjectMap.get("id").toString()));
            stringObjectMap.put("user_name", "姓名：" + userByMybatis.getCardName() + "\n 手机号：" + userByMybatis.getMobile() + "\n 身份证：" + userByMybatis.getCardNum());

            BigDecimal overdueMoney = BigDecimal.ZERO;

            Integer orderStatus = Integer.parseInt(stringObjectMap.get("status").toString());
            Boolean overdueStatus = true;
            if (stringObjectMap.containsKey("overdueStatus") && stringObjectMap.get("overdueStatus") != null) {
                overdueStatus = Boolean.parseBoolean(stringObjectMap.get("overdueStatus").toString());
            }
            if (orderStatus == OrderStatus.underway.getStatus().intValue() && !overdueStatus) {
                LoanOrderByMybatis search = new LoanOrderByMybatis();
                search.setOverdueStatus(false);
                search.setPayStatus(0);
                search.setId(Long.parseLong(stringObjectMap.get("orderId").toString()));
                LoanOrderBillByMybatis loanOrderBillByMybatis = loanOrderBillByMybatisMapper.selectSum(search);
                if (loanOrderBillByMybatis != null && loanOrderBillByMybatis.getMoney() != null) {
                    overdueMoney = loanOrderBillByMybatis.getMoney().add(loanOrderBillByMybatis.getRateMoney()).add(loanOrderBillByMybatis.getShopMoney()).subtract(loanOrderBillByMybatis.getPayMoney());
                }
            }
            stringObjectMap.put("overdueMoney", overdueMoney);

            //银行卡
            if (stringObjectMap.containsKey("bankId") && stringObjectMap.get("bankId") != null) {
                UserBankByMybatis userBankByMybatis = userBankByMybatisMapper.selectByPrimaryKey(Long.parseLong(stringObjectMap.get("bankId").toString()));
                if (userBankByMybatis != null) {
                    stringObjectMap.put("bankInfo", userBankByMybatis.getBankName() + "【" + userBankByMybatis.getCarNo() + "】");
                }
            }

            //最后一条放款记录
            PayOrderThirdByMybatis payOrderThirdByMybatis = payOrderThirdByMybatisMapper.selectLastLoanStatus(Long.parseLong(stringObjectMap.get("orderId").toString()));
            if (payOrderThirdByMybatis == null) {
                stringObjectMap.put("loanStatus", 1);
            } else if (payOrderThirdByMybatis.getStatus() == PayStatus.fail.getStatus().intValue()) {
                stringObjectMap.put("loanStatus", 4);
            } else if (payOrderThirdByMybatis.getStatus() == PayStatus.wait.getStatus().intValue()) {
                stringObjectMap.put("loanStatus", 2);
            } else if (payOrderThirdByMybatis.getStatus() == PayStatus.success.getStatus().intValue()) {
                stringObjectMap.put("loanStatus", 3);
            }
        }
    }


    /**
     * 列表数据统计行处理
     *
     * @return
     */
    public List<Row> setOrderListSumRow(String sqlEx) {
        //行对象
        List<Row> rows = new ArrayList<>();

        BigDecimal loanMoney = BigDecimal.ZERO, payMoneyByGuarantee = BigDecimal.ZERO, rateMoney = BigDecimal.ZERO,
                payMoney = BigDecimal.ZERO, discountMoney = BigDecimal.ZERO, discountsMoneyByGoods = BigDecimal.ZERO, overDueMoney = BigDecimal.ZERO;
        BigDecimal guarantee = BigDecimal.ZERO;

        LoanOrderByMybatis search = getDayOrderListSearch(null, null, null, null);
        search.setSqlEx(sqlEx);
        LoanOrderByMybatis loanOrderByMybatis = loanOrderByMybatisMapper.selectSum(search);
        if (loanOrderByMybatis != null) {
            loanMoney = loanOrderByMybatis.getMoney();
            payMoney = loanOrderByMybatis.getPayMoney();
            rateMoney = loanOrderByMybatis.getRateMoney();
            discountMoney = loanOrderByMybatis.getDiscountsMoney();
            discountsMoneyByGoods = loanOrderByMybatis.getDiscountsMoneyByGoods();
            guarantee = loanOrderByMybatis.getShopMoney();
        }
        //列对象
        List<Column> totalColumns = new ArrayList<>();
        totalColumns.add(Column.builder().value("").colspan(1).build());
        totalColumns.add(Column.builder().value("借款金额：" + loanMoney).colspan(1).className("text-red").build());
        totalColumns.add(Column.builder().value("总利息：" + rateMoney).colspan(1).className("text-red").build());
        totalColumns.add(Column.builder().value("担保费：" + guarantee).colspan(1).className("text-red").build());
        totalColumns.add(Column.builder().value("已还本息：" + payMoney).colspan(1).className("text-green").build());
        totalColumns.add(Column.builder().value("已还商品金额：" + payMoneyByGuarantee).colspan(1).className("text-green").build());
        totalColumns.add(Column.builder().value("优惠本息：" + discountMoney).colspan(1).className("text-green").build());
        totalColumns.add(Column.builder().value("优惠商品金额：" + discountsMoneyByGoods).colspan(1).className("text-green").build());

        rows.add(Row.builder().columns(totalColumns).build());
        return rows;
    }


    /**
     * 生成电子签
     *
     * @param orderId
     * @return
     */
    public String createSignContract(Long orderId, Boolean updateBill) {
        try {
            LoanOrderByMybatis loanOrderByMybatis = loanOrderByMybatisMapper.selectByPrimaryKey(orderId);
            if (loanOrderByMybatis == null) {
                return "订单不存在或订单状态异常";
            }
            if (updateBill != null && updateBill) {
                //重新生成账单
                loanOrderBillByMybatisMapper.deleteByOrderId(orderId);
                List<LoanOrderBillByMybatis> periodDateList = Util.getPeriodList(loanOrderByMybatis);
                for (int i = 0; i < periodDateList.size(); i++) {
                    LoanOrderBillByMybatis loanOrderBillByMybatis = periodDateList.get(i);
                    loanOrderBillByMybatisMapper.insertSelective(loanOrderBillByMybatis);
                }
            }

            //更新合同
            updateOrderContract(orderId);

            UserByMybatis userByMybatis = userByMybatisMapper.selectByOrderId(orderId);
            /**
             * 生成电子签
             */
            ResResult resResult = rentalDataUtil.createSignContract(orderId);
            if (resResult.getCode().intValue() != Code.SUCCESS.getCode()) {
                redisUtil.lpush(RedisCache.waitCreateContract, orderId + "");
                return resResult.getMsg();
            }
            JSONObject jsonObject = JSON.parseObject(resResult.getData().toString());
            if (!jsonObject.containsKey("signUser")) {
                redisUtil.lpush(RedisCache.waitCreateContract, orderId + "");
                return "电子签生成失败";
            }
            String signUrl = null;
            JSONArray signUsers = jsonObject.getJSONArray("signUser");
            for (Object signUser : signUsers) {
                JSONObject ItemSignUser = JSON.parseObject(signUser.toString());
                if (ItemSignUser.containsKey("idCard") || ItemSignUser.getString("idCard").trim().equals(userByMybatis.getCardNum())) {
                    signUrl = ItemSignUser.getString("signUrl");
                }
            }

            //插入签署认证记录
            LoanOrderSignLogByMybatis loanOrderSignLogByMybatis = new LoanOrderSignLogByMybatis();
            loanOrderSignLogByMybatis.setOrderId(orderId);
            loanOrderSignLogByMybatis.setCreateTime(new Date());
            loanOrderSignLogByMybatis.setContractNo(jsonObject.getString("contractNo"));
            loanOrderSignLogByMybatis.setUserSignUrl(signUrl);
            loanOrderSignLogByMybatis.setUserSignStatus(SignStatus.wait.getType());
            loanOrderSignLogByMybatisMapper.insertSelective(loanOrderSignLogByMybatis);

            LoanOrderByMybatis updateOrder = new LoanOrderByMybatis();
            updateOrder.setId(orderId);
            //订单合同签署状态
            updateOrder.setSignStatus(SignStatus.wait.getType());
            loanOrderByMybatisMapper.updateByPrimaryKeySelective(updateOrder);
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error(Util.GetErrorDetails(e));
            redisUtil.lpush(RedisCache.waitCreateContract, orderId + "");
        }
        return "电子签生成失败";
    }

}
